/*!
\file
	DataTypesManager.h
\brief
	Declaration of DataTypesManager.
\details
\bug
	none
\todo
	node
\date
	February 2, 2008 - first version of the file.
	March 16, 2008 - added get_or_create_data_type() method.
\author
	Copyright (C) 2008 Vadym Hulakov, mailto:hulakov@gmail.com. All rights reserved.
*/

#ifndef DATATYPEMANAGER_H
#define DATATYPEMANAGER_H

#include <map>
#include <string>

#include "Type.h"
#include "ClassType.h"

namespace ObjectModel
{
	typedef std::map<std::wstring, Type*> TypeMap;

	//! Class for work with various data type
	class TypeHierarchy : public TypeMap
	{
	public:
		//! @name Construction and destruction
		//@{
		//! Constructor
		TypeHierarchy(const wchar_t* name = L"fooHierarchy");

		//! Destructor
		~TypeHierarchy();

	private:
		// Disable copy constructor.
		TypeHierarchy(const TypeHierarchy& object);

		//! Disable assignment operator.
		TypeHierarchy& operator=(const TypeHierarchy& object);

		//@}

	public:
		//! @name Public methods
		//@{
		//! Create new data type and add it to manager.
		//! @param [in] name
		//!		Name of the data type.
		//! @param [in] description
		//!		Description of the data type.
		//! @return
		//!		Reference to created data type.
		ClassType& addClass(const wchar_t* name, const wchar_t* description = 0);


		//! Get data type with specified name.
		//! @param [in] name
		//!		Name of the data type.
		//! @return
		//		Requested data type.
		Type* lookup(const wchar_t* name) const;

		//! Get data type with specified name.
		//! @param [in] name
		//!		Name of the data type.
		//! @return
		//		Requested data type.
		template<typename T>
		T* lookup(const wchar_t* name) const
		{
			Type* type = lookup(name);
			T* result = dynamic_cast<T*>(type);
			return result;
		}

	//	//! Get data type with sepecified name.
	//	//! @param [in] name
	//	//!		Name of the data type.
	//	//! @param [in] create_empty_classes
	//	//!		Create empty classes for undefined data
	//	//!		types instead of using InvalidDataTypeInfo.
	//	//! @return
	//	//		Requested data type.
	//	DataTypeInfo& get_data_type(const wchar_t* name, bool create_empty_classes);
	//	//! Get count of data types.
	//	//! @return
	//	//!		Count of data types.
	//	int get_data_types_count();
	//	//! Try to get data type with sepecified name. If data type does not
	//	//! exist creates it and returns poiter to newly created data type.
	//	//! @param [in] name
	//	//!		Name of the data type.
	//	//! @return
	//	//		Requested data type.
	//	UserDataTypeInfo& get_or_create_class(const wchar_t* name);
	//	//! Try to get data type with sepecified name. If data type does not
	//	//! exist creates it and returns poiter to newly created data type.
	//	//! @param [in] name
	//	//!		Name of the data type.
	//	//! @return
	//	//		Requested data type.
	//	UserDataTypeInfo& get_or_create_class(const std::wstring& name);
	//	//! Checks is class with name exists.
	//	//! @param [in] name
	//	//!		Name of the data type.
	//	//! @return
	//	//		If class exists pointer to this class or 0 otherwise.
	//	DataTypeInfo* is_class_exists(const wchar_t* name);
	//	//! Checks is class with name exists.
	//	//! @param [in] name
	//	//!		Name of the data type.
	//	//! @return
	//	//		If class exists pointer to this class or 0 otherwise.
	//	DataTypeInfo* is_class_exists(const std::wstring& name);
		//@}

	//protected:

	//	//! @name Overloads
	//	//@{
	//	virtual const wchar_t* get_nature() const { return L"DataTypesManager"; };
	//	//@}
	//private:
	//	InvalidDataTypeInfo invalid_data_type_;
	//	//! Creates class and returns pointer to newly created data type.
	//	//! @param [in] name
	//	//!		Name of the data type.
	//	//! @return
	//	//		Requested data type.
	//	UserDataTypeInfo& create_class(const wchar_t* name);
	private:
		void createBasicTypes();
		void addBasicType(const wchar_t* name, int size);
		std::wstring _name;
	};
}

#endif // DATATYPEMANAGER_H
